package org.phalanx.gwt.client.shared;

import java.util.ArrayList;
import java.util.HashMap;

import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;

public class MessageManager implements RequestCallback {
	private HashMap<String,ArrayList<MessageListener>> listenerList;
	private WebClientFeedManager webFeed;
	private Timer t;
	private boolean feedOn = false;
	
	public MessageManager(){
		listenerList = new HashMap<String,ArrayList<MessageListener>>();
		webFeed = new WebClientFeedManager(this);
	}
	
	private void startTimer(){
		t = new Timer(){
			public void run(){
				if (!feedOn){
					initializeFeed();
				}
			}
		};
	}
	
	public void addMessageListener(String messageContext, MessageListener msgClass){
		if (messageContext != null && !messageContext.isEmpty()){
			ArrayList<MessageListener> msgClassList = listenerList.get(messageContext);
			
			if (msgClassList != null){
				if (!msgClassList.contains(msgClass)){
					msgClassList.add(msgClass);
				}
			}
			else {
				msgClassList = new ArrayList<MessageListener>();
				msgClassList.add(msgClass);
				listenerList.put(messageContext,msgClassList);
			}
		}
	}
	
	public void removeMessageListener(String messageContext, MessageListener msgClass){
		if (messageContext != null && !messageContext.isEmpty()){
			ArrayList<MessageListener> msgClassList = listenerList.get(messageContext);
			
			if (msgClassList != null){
				if (msgClassList.contains(msgClass)){
					msgClassList.remove(msgClass);
				}
				if (msgClassList.isEmpty()){
					listenerList.remove(messageContext);
				}
			}
		}
	}
	
	private void sendMessageToListeners(ServerMessage msg){
		ArrayList<MessageListener> msgClassList = listenerList.get(msg.getContext());
		
		if (msgClassList != null){
			for (int i = 0; i < msgClassList.size(); i++){
				MessageListener m = msgClassList.get(i);
				m.onMessageReceived(msg);
			}
		}
	}
	
	private ServerMessage convertIncomingMessage(String strMsg){
		ServerMessage aMsg = new ServerMessage();
		String contentsText = strMsg.substring(0,strMsg.indexOf(":"));

		if (!contentsText.isEmpty()){
			aMsg.setContext(contentsText);
			String[] arrayOfContents = strMsg.substring(strMsg.indexOf(":") + 1).split(",");

			if (arrayOfContents.length > 0){
				for (int i = 0; i < arrayOfContents.length; i++){
					String[] keyValue = arrayOfContents[i].split("=");

					if (keyValue.length > 0){
						aMsg.addMessageContents(keyValue[0], keyValue[1]);
					}
				}
			}
		}
		return aMsg;
	}
	
	@Override
	public void onError(Request request, Throwable exception) {
		// TODO Auto-generated method stub
		exception.getStackTrace();

	}

	@Override
	public void onResponseReceived(Request request, Response response) {
		ArrayList<String> queueMessages = getServerMessageFromQueue(response.getText());
		
		for (int i = 0; i < queueMessages.size(); i++){
			ServerMessage m  = convertIncomingMessage(queueMessages.get(i));
			sendMessageToListeners(m);
		}
	}
	
	public ArrayList<String> getServerMessageFromQueue(String responseText){
		ArrayList<String> textMessages = new ArrayList<String>();
		
		String[] queueMessage = responseText.split(";");
		
		if (queueMessage.length > 0){
			for (int i = 0; i < queueMessage.length; i++){
				String tempMsg = queueMessage[i];
				
				if (tempMsg.startsWith("{") && tempMsg.endsWith("}")){
					textMessages.add(tempMsg.substring(1, tempMsg.length() - 1));
				}				
			}
		}
		
		return textMessages;
	}
	
	public boolean initializeFeed(){
		boolean isSuccess = false;
		
		feedOn = true;
		webFeed.initiateFeed();
		feedOn=false;
		return isSuccess;
	}
	
	public void setFeedTimer(){
		startTimer();
		t.scheduleRepeating(2000);
	}
	
	synchronized public void sendMessage(ServerMessage msg){
		StringBuffer getStr = new StringBuffer();
		String requestData = null;
		
		getStr.append(msg.generateMessageBody());
		
		RequestBuilder msgSender;
		
		if (msg.getMessageTransport().equals(ServerMessage.IS_GET)){
			msgSender = new RequestBuilder(RequestBuilder.GET, "/PhalanxServlet/ServerInstance" +
					"?" + getStr.toString());
		}
		else {
			msgSender = new RequestBuilder(RequestBuilder.POST, "/PhalanxServlet/ServerInstance");
			msgSender.setHeader("Content-Type", "application/x-www-form-urlencoded");
			requestData = getStr.toString();
			
		}
		
		try {
			msgSender.sendRequest(requestData, webFeed);
		} catch (RequestException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
